import { shallowReadonly } from "../reactive/reactive"
import { emit } from "./componentEmit"
import { initProps } from "./componentProps"
import { publicInstanceHandler } from "./componentPublicInstance"
import { initSlots } from "./componentSlot"

export function createComponentInstance(vnode, parent) {
  const component = {
    vnode,
    setupState: {},
    props: {},
    slots: {},
    parent,
    provides: parent ? parent.provides : {},
    emit:()=> {}
  }
  component.emit = emit.bind(null, component) as any
  return component
}

export function setupComponent(instance) {
  initProps(instance, instance.vnode.props)
  initSlots(instance, instance.vnode.children)
  setupStatefulComponent(instance)
}

function setupStatefulComponent(instance: any) {
  const component = instance.vnode.type
  
  instance.proxy  = new Proxy(instance, publicInstanceHandler)
  const {setup} = component
  if(setup) {
    setCurrentInstance(instance)
    const setupResult = setup(shallowReadonly(instance.props), {
      emit: instance.emit,
      slots: instance.slots
    })
    setCurrentInstance(null)
    handleSetupResult(instance, setupResult)
  }
}
function handleSetupResult(instance, setupResult: any) {
  if(typeof setupResult === 'object') {
    instance.setupState = setupResult
  } 
  finishComponentSetup(instance)
}

function finishComponentSetup(instance: any) {
  const component = instance.vnode.type
  instance.render = component.render
}
let currentInstance = null
export function getCurrentInstance() {
  return currentInstance 
}
function setCurrentInstance(instance) {
  currentInstance = instance
}

